package com.cleaningcloud.erp.service.impl;

import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.security.utils.CommunityTypeConversionUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.api.domain.ErpCommodity;
import com.cleaningcloud.erp.api.domain.ErpCommodityStockAlter;
import com.cleaningcloud.erp.api.domain.ErpWareCommodityNumber;
import com.cleaningcloud.erp.api.utils.StockCommodityAlterUtils;
import com.cleaningcloud.erp.domain.ErpAccountsReceivable;
import com.cleaningcloud.erp.domain.ErpOutbound;
import com.cleaningcloud.erp.domain.ErpSale;
import com.cleaningcloud.erp.domain.dto.ErpOutboundDetailsDto;
import com.cleaningcloud.erp.domain.dto.ErpOutboundDto;
import com.cleaningcloud.erp.domain.vo.ErpOutboundDetailsVo;
import com.cleaningcloud.erp.domain.vo.ErpOutboundVo;
import com.cleaningcloud.erp.mapper.*;
import com.cleaningcloud.erp.service.IErpOutboundService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 销售出库Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-02
 */
@Service
public class ErpOutboundServiceImpl implements IErpOutboundService {

    @Autowired
    private ErpAccountsReceivableMapper erpAccountsReceivableMapper;

    @Autowired
    private ErpSaleMapper erpSaleMapper;

    @Autowired
    private ErpOutboundMapper erpOutboundMapper;

    @Autowired
    private ErpWareCommodityNumberMapper erpWareCommodityNumberMapper;

    @Autowired
    private ErpCommodityStockAlterMapper erpCommodityStockAlterMapper;

    @Autowired
    private ErpCommodityMapper erpCommodityMapper;

    /**
     * 查询销售出库
     *
     * @param outboundId 销售出库主键
     * @return 销售出库
     */
    @Override
    public ErpOutboundVo selectErpOutboundByOutboundId(Long outboundId) {
        ErpOutboundVo erpOutboundVo = erpOutboundMapper.selectErpOutboundByOutboundId(outboundId);
        for (ErpOutboundDetailsVo erpOutboundDetailsVo : erpOutboundVo.getDetailsList()) {
            erpOutboundDetailsVo.setCommodityType(CommunityTypeConversionUtils.conversion(erpOutboundDetailsVo.getCommodityType()));
            erpOutboundDetailsVo.setThisIssue(erpOutboundDetailsVo.getSaleNumber() - erpOutboundDetailsVo.getRealityNumber());
        }
        return erpOutboundVo;
    }

    /**
     * 查询销售出库列表
     *
     * @param erpOutbound 销售出库
     * @return 销售出库
     */
    @Override
    public List<ErpOutboundVo> selectErpOutboundList(ErpOutbound erpOutbound) {
        return erpOutboundMapper.selectErpOutboundList(erpOutbound);
    }

    /**
     * 新增销售出库
     *
     * @param erpOutbound 销售出库
     * @return 结果
     */
    @Override
    public int insertErpOutbound(ErpOutbound erpOutbound) {
        erpOutbound.setCreateTime(DateUtils.getNowDate());
        erpOutbound.setFlag("Y");
        erpOutbound.setCreateId(SecurityUtils.getUserId());
        erpOutbound.setCreateName(SecurityUtils.getUsername());
        erpOutbound.setIsHarvest(0);
        return erpOutboundMapper.insertErpOutbound(erpOutbound);
    }

    /**
     * 修改销售出库
     *
     * @param erpOutbound 销售出库
     * @return 结果
     */
    @Override
    @Transactional
    public int updateErpOutbound(ErpOutboundDto erpOutbound) {
        erpOutbound.setOutboundTime(new Date());
        ErpOutbound outbound = erpOutboundMapper.selectErpOutboundByOutboundId(erpOutbound.getOutboundId());
        if(null != outbound){
            ErpAccountsReceivable receivable = erpAccountsReceivableMapper.selectErpAccountsReceivableByReceivableId(outbound.getReceivableId());
            if(null != receivable){
                ErpSale sale = erpSaleMapper.getSaleInfoByNo(receivable.getOddNo());
                if(null != sale){
                    //收货修改销售单物流状态为已收货
                    if(erpOutbound.getIsHarvest() == 1){
                        sale.setLogisticsStauts("2");
                        erpSaleMapper.updateErpSale(sale);
                    }else if(erpOutbound.getIsHarvest() == 0){
                        sale.setLogisticsStauts("1");
                        erpSaleMapper.updateErpSale(sale);
                    }
                }
            }
        }
        // 修改销售出库明细
        // 统计总出已库量
        int totalSale = 0;
        // 统计销售总量
        int sumSale = 0;
        // 根据商品id和仓库id查询库存商品数量表 修改库存数量 （库存数量 - 出库数量=库存数量）
        for (ErpOutboundDetailsDto erpOutboundDetails : erpOutbound.getDetailsList()) {
            // 判断
            if (erpOutboundDetails.getThisIssueOut() > erpOutboundDetails.getSaleNumber()) {
                ErpCommodity commodity = erpCommodityMapper.selectErpCommodityByCommodityId(erpOutboundDetails.getCommodityId());
                if(null != commodity){
                    throw new RuntimeException("商品("+commodity.getCommodityName1()+")本期出库数量不可大于待出库数量！");
                }else{
                    throw new RuntimeException("本期出库数量不可大于待出库数量！");
                }
            }
            // 计算已出库
            erpOutboundDetails.setRealityNumber(erpOutboundDetails.getRealityNumber() + erpOutboundDetails.getThisIssueOut());
            totalSale += erpOutboundDetails.getRealityNumber();
            sumSale += erpOutboundDetails.getSaleNumber();
            // 计算待出库
            erpOutboundDetails.setPendingNumber(erpOutboundDetails.getSaleNumber() - erpOutboundDetails.getRealityNumber());
            erpOutboundMapper.updateErpOutboundDetails(erpOutboundDetails);
            ErpWareCommodityNumber query = new ErpWareCommodityNumber();
            query.setCommodityId(erpOutboundDetails.getCommodityId());
            //判断出库明细仓库ID是否为空
            if(null == erpOutboundDetails.getOutWareId()){
                query.setWareId(erpOutbound.getWareId());
            }else{
                query.setWareId(erpOutboundDetails.getOutWareId());
            }
            ErpWareCommodityNumber erpWareCommodityNumber = erpWareCommodityNumberMapper.selectByCommodityIdAndWareId(query);
            // 出库数量不能大于库存商品数量
            if (erpWareCommodityNumber.getCommodityNumber() < erpOutboundDetails.getThisIssueOut()) {
                ErpCommodity commodity = erpCommodityMapper.selectErpCommodityByCommodityId(erpOutboundDetails.getCommodityId());
                if(null != commodity){
                    throw new RuntimeException("商品("+commodity.getCommodityName1()+")本期出库数量不可大于库存商品数量！");
                }else{
                    throw new RuntimeException("本期出库数量不可大于库存商品数量！");
                }
            }
            erpWareCommodityNumber.setCommodityNumber(erpWareCommodityNumber.getCommodityNumber() - erpOutboundDetails.getThisIssueOut());
            erpWareCommodityNumber.setWareId(query.getWareId());
            erpWareCommodityNumberMapper.updateErpWareCommodityNumber(erpWareCommodityNumber);

            // 新增库存商品变更记录信息
            ErpCommodityStockAlter erpCommodityStockAlter = StockCommodityAlterUtils.AssemblyInfo(erpOutboundDetails.getCommodityId(), BigDecimal.valueOf(erpOutboundDetails.getThisIssueOut()).negate(), "2", erpOutbound.getWareId());
            erpCommodityStockAlterMapper.insertErpCommodityStockAlter(erpCommodityStockAlter);
        }
        // 已入库量等于采购总量 修改状态为已入库
        if (sumSale == totalSale) {
            erpOutbound.setOutboundStatus(2);
        }
        return erpOutboundMapper.updateErpOutbound(erpOutbound);
    }

    /**
     * 批量删除销售出库
     *
     * @param outboundIds 需要删除的销售出库主键
     * @return 结果
     */
    @Override
    public int deleteErpOutboundByOutboundIds(Long[] outboundIds) {
        return erpOutboundMapper.deleteErpOutboundByOutboundIds(outboundIds);
    }

    /**
     * 删除销售出库信息
     *
     * @param outboundId 销售出库主键
     * @return 结果
     */
    @Override
    public int deleteErpOutboundByOutboundId(Long outboundId) {
        return erpOutboundMapper.deleteErpOutboundByOutboundId(outboundId);
    }

}
